package com.zsc.shixun.service.function.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zsc.shixun.contant.Contant;
import com.zsc.shixun.entity.Article;
import com.zsc.shixun.entity.Notice;
import com.zsc.shixun.entity.User;
import com.zsc.shixun.model.unauthorize.index.ArticleListVO;
import com.zsc.shixun.model.unauthorize.index.UserListVO;
import com.zsc.shixun.service.IArticleService;
import com.zsc.shixun.service.INoticeService;
import com.zsc.shixun.service.IUserService;
import com.zsc.shixun.service.function.IndexService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 博客页
 * </p>
 *
 * @author ZWYZY
 * @since 2020/6/19
 */
@Service
@Transactional
public class IndexServiceImpl implements IndexService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private IArticleService articleService;
    @Autowired
    private IUserService userService;

    @Autowired
    private INoticeService noticeService;

    @Override
    public List<ArticleListVO> getArticleList() {
        if (redisTemplate.hasKey(Contant.INDEX_ARTICLE_KEY)) {
            return (List<ArticleListVO>) redisTemplate.opsForValue().get(Contant.INDEX_ARTICLE_KEY);
        }
        List<ArticleListVO> list = new ArrayList<>(10);
        List<Article> articleList = articleService.list(new QueryWrapper<Article>().lambda().eq(Article::getIsRelease, true).orderByDesc(Article::getCreateTime));
        articleList.forEach(a -> {
            ArticleListVO articleListVO = new ArticleListVO();
            articleListVO.setArticle(a);
            articleListVO.setUser(userService.getById(a.getUserId()));
            list.add(articleListVO);
        });
//        for (Article a : articleList
//        ) {
//            ArticleListVO articleListVO = new ArticleListVO();
//            articleListVO.setArticle(a);
//            articleListVO.setUser(userService.getById(a.getUserId()));
//            list.add(articleListVO);
//        }
        redisTemplate.opsForValue().set(Contant.INDEX_ARTICLE_KEY, list);
        return list;
    }

    @Override
    public Notice getNotice() {
        if (redisTemplate.hasKey(Contant.INDEX_NOTICE_KEY)) {
            return (Notice) redisTemplate.opsForValue().get(Contant.INDEX_NOTICE_KEY);
        }
        Notice notice = noticeService.list(new QueryWrapper<Notice>().lambda().orderByDesc(Notice::getCreateTime)).get(0);
        redisTemplate.opsForValue().set(Contant.INDEX_NOTICE_KEY, notice);
        return notice;
    }

    @Override
    public List<UserListVO> getTop10() {
        if (redisTemplate.hasKey(Contant.INDEX_TOP10_KEY)) {
            return (List<UserListVO>) redisTemplate.opsForValue().get(Contant.INDEX_TOP10_KEY);
        }
        List<UserListVO> list = new ArrayList<>(10);
        List<User> userList = userService.list();
        userList.forEach(user -> {
            UserListVO userListVO = new UserListVO();
            userListVO.setUser(user);
            userListVO.setClickNumber(articleService.list(new QueryWrapper<Article>().lambda().eq(Article::getUserId, user.getId())).stream().mapToLong(Article::getClickNumber).sum());
            list.add(userListVO);
        });
//        for (User user : userList
//        ) {
//            UserListVO userListVO = new UserListVO();
//            userListVO.setUser(user);
//            userListVO.setClickNumber(articleService.list(new QueryWrapper<Article>().lambda().eq(Article::getUserId, user.getId())).stream().mapToLong(Article::getClickNumber).sum());
//            list.add(userListVO);
//        }
        List<UserListVO> top10list = list.stream().sorted(Comparator.comparingLong(UserListVO::getClickNumber).reversed()).limit(10).collect(Collectors.toList());
        redisTemplate.opsForValue().set(Contant.INDEX_TOP10_KEY, top10list);

        return top10list;
    }
}
